package worktable

import (
	"os"
	"runtime"
	"strings"
	"time"

	"gitee.com/xuesongtao/collect/app/dao"
	"gitee.com/xuesongtao/gotool/base"

	pslog "gitee.com/xuesongtao/ps-log"
	"gitee.com/xuesongtao/ps-log/line"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/os/glog"
)

func AddLogPath() {
	collectProjectDirs := g.Cfg().GetStrings("pusherrlog.collect_project_dirs")
	collectSrcs := g.Cfg().GetStrings("pusherrlog.collect_src_dirs")
	excludeProjectDirs := g.Cfg().GetStrings("pusherrlog.exclude_project_dirs")
	excludeTailProjectDirs := g.Cfg().GetStrings("pusherrlog.exclude_tail_project_dirs")
	glog.Info("collectProjectDirs: ", collectProjectDirs)
	glog.Info("collectSrcs: ", collectSrcs)
	glog.Info("excludeProjectDirs: ", excludeProjectDirs)
	glog.Info("excludeTailProjectDirs: ", excludeTailProjectDirs)

	curDate := time.Now().Format(base.DateFmt)
	// 查找内容已经在注册过了 InitPlg
	logName := curDate + ".log"                                              // xxxx-xx-xx.log 中查找满足 [ERRO]
	errorLogName := "error-" + strings.ReplaceAll(curDate, "-", "") + ".log" // error-xxxxxxxx.log 中查找满足 "500 "
	obj := pslog.NewLogPath()
	obj.SetExcludeProjectDir(excludeProjectDirs...)

	// 处理待收集的 log path
	logPaths := make([]*pslog.ProjectLog, 0) // 待监听的 log path
	// 项目
	if len(collectProjectDirs) > 0 {
		for _, dir := range collectProjectDirs {
			namespace, path := dao.ParsePath(dir)
			res := obj.ParseLogPath(&pslog.Project{
				LogDir: &pslog.LogDir{
					TargetNames: []string{logName, errorLogName},
					Namespace:   namespace,
				},
				ProjectPath: path,
			})
			logPaths = append(logPaths, res...)
		}
	}
	// src
	if len(collectSrcs) > 0 {
		for _, src := range collectSrcs {
			namespace, path := dao.ParsePath(src)
			res := obj.ParseSrc(&pslog.ProjectSrc{
				LogDir: &pslog.LogDir{
					TargetNames: []string{logName, errorLogName},
					Namespace:   namespace,
				},
				SrcPath: path,
			})
			logPaths = append(logPaths, res...)
		}
	}
	if len(logPaths) == 0 {
		glog.Info("logPaths is null, it is skip")
		return
	}

	// 添加监听文件
	// 默认按照全局注册的 Tail 处理, 判断下需要排除的
	excludeTailProjectDirsMap := make(map[string]bool, len(excludeTailProjectDirs))
	for _, dir := range excludeTailProjectDirs {
		excludeTailProjectDirsMap[dir] = true
	}
	for _, lp := range logPaths {
		h := GetPlgDefaultHandler()
		for _, dir := range excludeTailProjectDirs {
			if strings.Contains(lp.LogPath, dir) {
				h.Tail = false // 定时处理
				break
			}
		}
		h.Tail = !dao.DelayPushObj.NeedDelay() // 判断下是否需要实时
		h.Ext = dao.JoinPath(lp.Namespace, lp.ProjectName)

		// 处理 error log
		if strings.Contains(lp.LogPath, errorLogName) {
			h.Targets = []*pslog.Target{
				{
					Content: " 500 ", // error-xxxxxxxx.log 中查找满足 "500 "
					To:      []pslog.PsLogWriter{&dao.ToDingDing{}},
				},
			}
			mul := line.NewMulti()
			if err := mul.StartPattern(`\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3}`); err != nil {
				glog.Error("mul.StartPattern is failed, err:", err)
				continue
			}
			h.MergeRule = mul
		}

		if err := plg.ReplacePath2Handler(lp.LogPath, h); err != nil {
			glog.Error("plg.ReplacePath2Handler is failed, err:", err)
		}
	}
	glog.Info(plg.List())
	printHeapInfo()
}

// CronCollectErrLog2Push 定时采集
func CronCollectErrLog2Push() {
	AddLogPath()
	plg.CronLogs()

}

func printHeapInfo() {
	var m runtime.MemStats
	runtime.ReadMemStats(&m)
	glog.Infof("env:%v, heapsys:%d,heapalloc:%d,heapidel:%d,heapreleased:%d,heapinuse:%d",
		os.Getenv("GODEBUG"), m.HeapSys, m.HeapAlloc, m.HeapIdle, m.HeapReleased, m.HeapInuse)
}
